package com.yumingjaing.thread;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * @description:
 * @author: John
 * @version: TestAtomcity.java, v1.0 2024年12月15日 08:08
 */
public class TestAtomicity {
    private static int count;

    public static void increment(){
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        count++;
    }

    /**
     * synchronized 实现防止线程竞争导致的数据不一致的问题
     *
     * 数据错误的根因：count++ 对应这cup会是多条指令，当一次++的指定完全没有执行完的时候，其他的指令穿插进来的，造成了数据不一致的问题
     * 加锁后，就会用锁将多条指令包裹起来，实现了线程安全。
     */
    private static void t1() throws InterruptedException {
        Object o = new Object();
        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 100; i++) {
                synchronized (o) {
                    increment();
                }
            }
        });
        Thread t2 = new Thread(() -> {
            for (int i = 0; i < 100; i++) {
                synchronized (o) {
                    increment();
                }
            }
        });
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println(count);
    }
    private static AtomicInteger atomicInteger = new AtomicInteger(0);

    /**
     * 利用AtomicInteger 在这个里面有实现了cas的逻辑，cas在汇编层面执行前会加lock指令，所以线程安全。
     *
     *     @IntrinsicCandidate
     *     public final int getAndAddInt(Object o, long offset, int delta) {
     *         int v;
     *         do {
     *             v = getIntVolatile(o, offset);
     *         } while (!weakCompareAndSetInt(o, offset, v, v + delta));
     *         return v;
     *     }
     * @throws InterruptedException
     */
    private static void t2() throws InterruptedException {
        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 100; i++) {
                atomicInteger.incrementAndGet();
            }
        });
        Thread t2 = new Thread(() -> {
            for (int i = 0; i < 100; i++) {
                atomicInteger.incrementAndGet();
            }
        });
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println(atomicInteger);

    }
    public static void main(String[] args) throws InterruptedException {
//       t1();
        t2();
    }
}